#include "terminal.h"
#include <sys/ioctl.h>
#include <unistd.h>

namespace CTUI
{

    int terminalWidth()
    {
        struct winsize w;
        ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
        return w.ws_col;
    }

    int startCenterPosition(int len)
    {
        return (terminalWidth() - len) / 2;
    }
    
    void positionPrint(int startPos, const char *str)
    {
        MOVERIGHT(startPos);
        std::cout << str << std::endl;
    }

    void positionPrint(int startPos, const std::string &str)
    {
        positionPrint(startPos, str.c_str());
    }

    void centerPrint(const char *str)
    {
        int x = startCenterPosition(strlen(str));
        positionPrint(x, str);
    }

    void centerPrint(const std::string &str)
    {
        centerPrint(str.c_str());
    }

    void borderPrint(int startPos, int width, char borderStyle, const char *str)
    {
        int len = strlen(str);
        int maxLen = width - 4;
        if (len > maxLen)
        {
            // 超过边框显示宽度时将截取字符串分多行显示
            // 使用递归的方式多行显示字符串
            int pos = 0;
            while(len > 0)
            {
                int l = maxLen + 1;
                char *t = new char[l];
                memset(t, 0, l);
                memcpy(t, str + pos, maxLen);
                borderPrint(startPos, width, borderStyle, t);
                pos += maxLen;
                len -= maxLen;

                delete []t;
                t = nullptr;
            }
        }
        else
        {
            // 当一行可以显示所有内容时，需要计算最后输出的空格数
            // 空格输出个数 = 宽度 - 字符串长度 - (2 个边框字符 + 1 个空格)
            int spaceLen = width - len - 3;
            std::string space(spaceLen, ' ');
            MOVERIGHT(startPos);
            std::cout << borderStyle << ' ' << str << space << borderStyle << std::endl;
        }
    }

    void borderPrint(int startPos, int width, char borderStyle, const std::string &str)
    {
        borderPrint(startPos, width, borderStyle, str.c_str());
    }
    
    void borderCenterPrint(int startPos, int width, char borderStyle, const char *str)
    {
        int len = strlen(str);
        int maxLen = width - 4;
        if (len > maxLen)
        {
            // 超过边框显示宽度时将截取字符串分多行显示
            // 使用递归的方式多行显示字符串
            int pos = 0;
            while(len > 0)
            {
                int l = maxLen + 1;
                char *t = new char[l];
                memset(t, 0, l);
                memcpy(t, str + pos, maxLen);
                borderPrint(startPos, width, borderStyle, t);
                pos += maxLen;
                len -= maxLen;

                delete []t;
                t = nullptr;
            }
        }
        else
        {
            // 当一行可以显示所有内容时，需要计算前后输出的空格数
            // 空格输出个数 = 宽度 - 字符串长度 - 2 个边框字符
            int spaceLen = (width - len - 2) / 2;
            std::string space(spaceLen, ' ');
            MOVERIGHT(startPos);
            std::cout << borderStyle << space << str << space << borderStyle << std::endl;
        }
    }
    
    void borderCenterPrint(int startPos, int width, char borderStyle, const std::string &str)
    {
        borderCenterPrint(startPos, width, borderStyle, str.c_str());
    }

} // end of namespace CTUI